package com.katze.boot.applet.ssh.controller;

import com.katze.boot.applet.ssh.entity.SshProcessEntity;
import com.katze.boot.applet.ssh.entity.SshSessionEntity;
import com.katze.boot.applet.ssh.service.SecureShellService;
import com.katze.boot.plugins.security.annotations.RestControllerMapping;
import com.katze.boot.plugins.security.annotations.RestRequestMapping;
import com.katze.common.Message;
import com.katze.common.controller.BaseController;
import com.katze.ssh.SSHException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMethod;

import java.util.Date;
import java.util.List;

@RestControllerMapping({"/ssh"})
public class SecureShellController extends BaseController {

    @Autowired
    private SecureShellService secureShellService;

    @RestRequestMapping(value = "/session", method = RequestMethod.GET, skip = true, permits = "secure:ssh:view")
    public Message sessionList(SshSessionEntity entity) {
        List<SshSessionEntity> rs = secureShellService.findSessions(entity);
        return Message.ok().data(rs);
    }

    @RestRequestMapping(value = "/session", method = {RequestMethod.POST, RequestMethod.PUT}, description = "编辑会话信息")
    public Message edit(SshSessionEntity entity){
        boolean isUpdate = entity.getId() != null;
        if (!isUpdate) {
            entity.setCreateTime(new Date());
        }
        boolean rs = secureShellService.saveOrUpdate(entity);
        if (isUpdate) {
            return rs? Message.ok("主机信息修改成功"):Message.error("主机信息可能不存在");
        } else {
            return rs? Message.ok("主机信息添加成功"):Message.error("主机信息添加失败");
        }
    }

    @RestRequestMapping(value = "/session", method = RequestMethod.DELETE, description = "删除会话记录")
    public Message deleteSession(String id){
        boolean rs = secureShellService.deleteSessionById(id);
        return rs? Message.ok("删除成功"):Message.error("删除失败");
    }

    @RestRequestMapping(value = "/session/exit", method = RequestMethod.DELETE, description = "退出会话连接")
    public Message exit(String id){
        secureShellService.exit(id);
        return Message.ok();
    }

    @RestRequestMapping(value = "/process", method = RequestMethod.GET, skip = true, permits = "secure:ssh:view:precess")
    public Message processList(String sessionId) throws Exception {
        try {
            return toDataTable(secureShellService.findProcessBySession(sessionId));
        } catch (SSHException e) {
            return Message.error(e.getMessage());
        }
    }

    @RestRequestMapping(value = "/process/name", method = RequestMethod.GET, skip = true)
    public Message searchProcess(String owner, String name) {
        return Message.ok().data(secureShellService.findProcessName(owner, name));
    }

    @RestRequestMapping(value = "/process", method = {RequestMethod.POST, RequestMethod.PUT}, description = "编辑进程信息")
    public Message edit(SshProcessEntity entity){
        boolean isUpdate = entity.getId() != null;
        if (!isUpdate) {
            entity.setCreateTime(new Date());
        }
        boolean rs = secureShellService.saveOrUpdate(entity);
        if (isUpdate) {
            return rs? Message.ok("进程信息修改成功"):Message.error("进程信息修改失败");
        } else {
            return rs? Message.ok("进程信息创建成功"):Message.error("进程信息创建失败");
        }
    }

    @RestRequestMapping(value = "/process", method = RequestMethod.DELETE, description = "删除进程记录")
    public Message deleteProcess(String id){
        boolean rs = secureShellService.deleteProcessById(id);
        return rs? Message.ok("删除成功"):Message.error("删除失败");
    }

    /**
     * 执行启动或关闭命令
     * @param sessionId 会话ID
     * @param cmd 命令类型
     * @param processes 既可以表示实际进程PID也可以表示进程对象的ID，通过值的长度判断
     */
    @RestRequestMapping(value = "/process/{cmd}", method = RequestMethod.PUT, description = "执行进程命令")
    public Message execute(@PathVariable("cmd") String cmd, String sessionId, String[] processes) throws Exception {
        try {
            return Message.ok().data(secureShellService.execute(cmd, sessionId, processes));
        } catch (SSHException e) {
            return Message.error(e.getMessage());
        }
    }
}
